﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using CarolLib;

namespace StockMonitor
{
    /// <summary>
    /// 股票池，即用于自动交易的股票配置成分。
    /// 其中卖出池还负责当前持仓情况的刷新与保存。
    /// </summary>
    /// <remarks>
    /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
    /// 编写时间：<datetime>2012-10-16 5:41 PM</datetime>
    /// </remarks>
    public class StockPool
    {
        public static StockPool Instance = new StockPool();

        #region Properties

        private List<StockPoolItem> pool = new List<StockPoolItem>();

        public List<StockPoolItem> Pool
        {
            get { return pool; }
            set { pool = value; }
        }

        /// <summary>
        /// 买入池.
        /// </summary>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:41 PM</datetime>
        /// </remarks>
        public List<StockPoolItem> BuyPool
        {
            get
            {
                if (pool.Count(s => s.IsBuy)<=0)
                {
                    return new List<StockPoolItem>();
                }
                return pool.Where(s => s.IsBuy).ToList();
            }
        }

        /// <summary>
        /// 卖出池.（包含当前的持仓状态）
        /// </summary>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:41 PM</datetime>
        /// </remarks>
        public List<StockPoolItem> SellPool
        {
            get
            {
                if (pool.Count(s => !s.IsBuy) <= 0)
                {
                    return new List<StockPoolItem>();
                }
                return pool.Where(s => !s.IsBuy).ToList();
            }
        }

        /// <summary>
        /// 股票池文件保存路径.
        /// </summary>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:41 PM</datetime>
        /// </remarks>
        string StockPoolPath
        {
            get
            {
                return System.Windows.Forms.Application.StartupPath + System.Configuration.ConfigurationManager.AppSettings["StockPool"];
            }
        }

        #endregion

        #region Ctor.

        private StockPool()
        {
            ReLoad();
        }

        #endregion

        #region CRUD

        /// <summary>
        /// 重新加载股票池.
        /// 1.从本地股票池文件加载
        /// 2.调用接口查询持仓情况
        /// 3.并同步到本地股票池文件
        /// </summary>
        /// <returns>是否成功</returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:42 PM</datetime>
        /// </remarks>
        public bool ReLoad()
        {
            try
            {
                string txt = File.ReadAllText(this.StockPoolPath).Trim();
                if (txt == string.Empty)
                    pool = new List<StockPoolItem>();
                else
                    pool = CarolLib.XmlSerializeHelper.ConvertToObject<List<StockPoolItem>>(txt);

                return RefreshStockPosition();
            }
            catch (Exception e)
            {
                Log.Exception("加载股票配置失败！", e);
                return false;
            }
        }

        /// <summary>
        /// 保存股票池到文件.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:48 PM</datetime>
        /// </remarks>
        public bool Save()
        {
            try
            {
                string txt = CarolLib.XmlSerializeHelper.ConvertToString(pool).Trim();
                File.WriteAllText(this.StockPoolPath, txt);
                return true;
            }
            catch (Exception e)
            {
                //log

                Log.Exception("保存股票配置失败！", e);
                return false;
            }
        }

        /// <summary>
        /// 调用接口，刷新股票池中现有股票（卖出池）的持仓信息.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:44 PM</datetime>
        /// </remarks>
        public bool RefreshStockPosition()
        {
            try
            {
                //query from hs.
                var hsresult = AuthUserContext.Instance.QueryStockPosistion();

                if (hsresult == null)
                    return false;

                //remove old.
                pool.RemoveAll(s => (s.IsBuy == false) && (!hsresult.Select(h => h.stock_code).Contains(s.StockCode)));

                if (hsresult.Count == 0)
                    return true;

                //add new.
                var newhs = hsresult.Where(h => !SellPool.Select(s => s.StockCode).Contains(h.stock_code));
                foreach (var item in newhs)
                    pool.Add(new StockPoolItem() { StockCode = item.stock_code, StockName = item.stock_name, IsBuy = false });

                //update data.
                var hsdic = hsresult.ToDictionary(h => h.stock_code);
                SellPool.ForEach(s =>
                {
                    s.CurrentAmount = Convert.ToInt32(hsdic[s.StockCode].current_amount);
                    s.EnableAmount = Convert.ToInt32(hsdic[s.StockCode].enable_amount);
                });

                return true;
            }
            catch (Exception e)
            {
                Log.Exception("更新股票持仓信息时发生错误", e);
                return false;
            }
        }

        /// <summary>
        /// 更新当日成交累计.(从交易管理类中)
        /// </summary>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:25 PM</datetime>
        /// </remarks>
        public void RefreshTodayExchangeSum()
        {
            try
            {
                StockPool.Instance.BuyPool.ForEach(s =>
                {
                    var ts = TradeContext.Instance.TodayBusiness.Where(t => t.StockCode == s.StockCode && t.Entrustbs == Enums.EntrustBs.买入);
                    if (ts != null)
                        s.TodayExchangeSummary = Convert.ToInt32(ts.Sum(b => b.BusinessAmount));
                });

                StockPool.Instance.SellPool.ForEach(s =>
                {
                    var ts = TradeContext.Instance.TodayBusiness.Where(t => t.StockCode == s.StockCode && t.Entrustbs == Enums.EntrustBs.卖出);
                    if (ts != null)
                        s.TodayExchangeSummary = Convert.ToInt32(ts.Sum(b => b.BusinessAmount));
                });


                //var buydic = StockPool.Instance.BuyPool.ToDictionary(s => s.StockCode);

                //TradeContext.Instance.TodayBusiness.ForEach(t =>
                //{
                //    if (buydic.ContainsKey(t.StockCode) && buydic[t.StockCode].StockCode != null && t.Entrustbs == Enums.EntrustBs.买入)
                //    {
                //        buydic[t.StockCode].TodayExchangeSummary += Convert.ToInt32(t.BusinessAmount);
                //    }
                //});

                //var selldic = StockPool.Instance.SellPool.ToDictionary(s => s.StockCode);

                //TradeContext.Instance.TodayBusiness.ForEach(t =>
                //{
                //    if (selldic.ContainsKey(t.StockCode) && selldic[t.StockCode].StockCode != null && t.Entrustbs == Enums.EntrustBs.卖出)
                //    {
                //        selldic[t.StockCode].TodayExchangeSummary += Convert.ToInt32(t.BusinessAmount);
                //    }
                //});

            }
            catch (Exception e)
            {
                Log.Exception("更新当日成交累计时发生错误", e);
            }
        }
        
        #endregion
    }

}
